<?php
/**
 * CRM 数据迁移工具
 */
class MigrateTask extends \Formax\CLI\Task
{

    public function registerOptions()
    {
        $this
            ->registerOption('clean',      'cl', false, false, '清空相关数据表后导入')
            ->registerOption('detail',     'dt', false, false, '显示详细导入过程')
            ->registerOption('all',        'al', false, false, '导入所有数据')
            ->registerOption('country',    'ct', false, false, '导入国家信息数据')
            ->registerOption('department', 'dp', false, false, '导入部门数据')
            ->registerOption('user',       'us', false, false, '导入用户数据')
            ->registerOption('customer',   'cu', false, false, '导入客户数据')
            ->registerOption('assign',     'as', false, false, '导入客户分配数据')
            ->registerOption('log',        'lg', false, false, '导入客户跟进日志');
    }

    public function mainAction()
    {
        if ($this->args->isEmpty()) {
            return $this->displayHelp();
        }

        if ($this->args->all) {
            if ($this->args->clean) {
                cli_output('清空 formax_crm.oa_translates 表 ...');
                $this->db->query('truncate formax_crm.oa_translates');
            }

            $this->importAll();
        } else {
            if ($this->args->country)    $this->importCountries();
            if ($this->args->department) $this->importDepartments();
            if ($this->args->user)       $this->importUsers();
            if ($this->args->customer)   $this->importCustomers();
            if ($this->args->assign)     $this->importCustomerAssign();
            if ($this->args->log)        $this->importCustomerLogs();
        }
    }

    public function importAll()
    {
        $this->importCountries();
        $this->importDepartments();
        $this->importUsers();
        $this->importCustomers();
        $this->importCustomerAssign();
        $this->importCustomerLogs();
    }

    public function importCountries()
    {
        cli_output(PHP_EOL . '准备导入国家信息数据', 'info');

        if (PRODUCTION) {
            cli_output('正式环境，跳过导入国家信息数据', 'info');

            return ;
        }

        $e4maxDB = service('db.e4max');

        if ($this->args->clean) {
            cli_output('清空 formax_crm.oa_countries 表 ...');
            $this->db->query('truncate formax_crm.oa_countries');
        }

        $result = $e4maxDB->query('select * from e4max_user_info.t_sort where parentid=1 order by id asc');
        cli_output('查询 e4max_user_info.t_sort 表，共' . $result->numRows() . '条记录...');
        $oldRows = array();
        while ($row = $result->fetch()) {
            $oldRows[$row['name']] = $row;
            $oldRows[$row['description']] = $row;
        }

        $succes_nums = 0;
        $reader = csv_reader(ROOT_PATH . '/docs/countries.csv');
        $i18ns  = array();
        while ($row = $reader->getRow()) {
            $data = array(
                'country'       => $row['country'],
                'abbr'          => $row['abbr'],
                'area_code'     => $row['area_code'],
                'time_diff'     => $row['time_diff'],
                'enabled'       => 1,
                'copymaster_id' => 0,
            );

            $i18ns[$row['country']] = $row['country_cn'];

            if (isset($oldRows[$row['country_cn']])) {
                $data['copymaster_id'] = $oldRows[$row['country_cn']]['id'];
            } elseif (isset($oldRows[$row['country']])) {
                $data['copymaster_id'] = $oldRows[$row['country']]['id'];
            }

            /*
                受到联合国制裁的国家不予显示:
                    The Republic of Cote divoire
                141 Democratic Peoples Republic of Korea
                    Democratic Republic of the Congo
                    Eritrea
                130 Iran
                147 Lebanon
                149 Liberia
                150 Libya
                216 Somalia
                220 Sudan
            */
            if (in_array($data['copymaster_id'], array(141, 130, 147, 149, 150, 216, 220))) {
                $data['enabled'] = false;
            }

            $model = new \OaCountries;
            if ($success = $model->create($data)) {
                $succes_nums++;
                if ($this->args->detail) {
                    cli_output('[成功] => ' . implode(', ', $data));
                } else {
                    echo '>';
                }
            } else {
                if ($this->args->detail) {
                    cli_output('[失败] => ' . $model->getMessage(), 'error');
                } else {
                    echo '.';
                }
            }
        }

        $content = "<?php\nreturn " . var_export($i18ns, true) . ";";

        if (! file_put_contents(APP_PATH . '/i18n/zh-cn/country.php', $content)) {
            cli_output('写入语言包失败！', 'error');
        }

        cli_output(PHP_EOL . '国家信息数据导入完成，共成功' . $succes_nums . '条记录', 'success');
    }

    public function importDepartments()
    {
        cli_output(PHP_EOL . '准备导入部门数据', 'info');
        $db = $this->db;

        if ($this->args->clean) {
            cli_output('清空 formax_crm.oa_departments 表 ...');
            $db->query('truncate formax_crm.oa_departments');

            $db->query("DELETE FROM formax_crm.oa_translates where keyword='department'");

            $time = time();

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (1,'Sales & Trading Dept.',0,'1;',99,0,$time,$time)");
            \OaTranslates::write('department', 1, '销售与交易部', 'zh-cn');

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (2,'Trading Dept.',1,'1;2;',99,0,$time,$time)");
            \OaTranslates::write('department', 2, '交易部', 'zh-cn');

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (3,'Overseas Sales Dept.',1,'1;3;',99,0,$time,$time)");
            \OaTranslates::write('department', 3, '海外销售部', 'zh-cn');

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (4,'China Sales Dept.',1,'1;4;',99,0,$time,$time)");
            \OaTranslates::write('department', 4, '国内销售部', 'zh-cn');

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (5,'Internet Business Dept.',0,'5;',99,0,$time,$time)");
            \OaTranslates::write('department', 5, '互联网事业部', 'zh-cn');

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (6,'Product Dept.',5,'5;7;',99,0,$time,$time)");
            \OaTranslates::write('department', 6, '产品部', 'zh-cn');

            $db->query("INSERT INTO formax_crm.oa_departments VALUES (7,'R&D Dept.',5,'5;7;',99,0,$time,$time)");
            \OaTranslates::write('department', 7, '研发部', 'zh-cn');
        }

        $result = $db->query('select * from formaxcrm.crm_department order by id asc');
        cli_output('查询 formaxcrm.crm_department 表，共' . $result->numRows() . '条记录...');

        $succes_nums = 0;
        while ($row = $result->fetch()) {
            $parent_id = in_array($row['id'], array(14,15,16)) ? 4 : 3;
            $data = array(
                'dept_id' => $row['id'],
                'department'    => $row['name_en-us'],
                'parent_id'     => $parent_id,
                'depth_path'    => "1;{$parent_id};{$row['id']};",
                'sort_order'    => 99,
                'ctime'         => time(),
            );

            // 保存翻译文本
            \OaTranslates::write('department', $row['id'], $row['name_zh-cn'], 'zh-cn');

            $model = new \OaDepartments;
            if ($success = $model->create($data)) {
                $succes_nums++;
                if ($this->args->detail) {
                    cli_output('[成功] => ' . implode(', ', $data));
                } else {
                    echo '>';
                }
            } else {
                if ($this->args->detail) {
                    cli_output('[失败] => ' . $model->getMessage(), 'error');
                } else {
                    echo '.';
                }
            }

        }
        cli_output(PHP_EOL . '部门数据导入完成，共成功' . $succes_nums . '条记录', 'success');
    }

    public function importUsers()
    {
        cli_output(PHP_EOL . '准备导入用户相关数据', 'info');
        $db = $this->db;

        if ($this->args->clean) {
            cli_output('清空 formax_crm.oa_users 表 ...');
            $db->query('truncate formax_crm.oa_users');

            cli_output('清空 formax_crm.oa_sales_merchants 表 ...');
            $db->query('truncate formax_crm.oa_sales_merchants');

            cli_output('清空 formax_crm.oa_department_users 表 ...');
            $db->query('truncate formax_crm.oa_department_users');

            cli_output('清空 formax_crm.oa_roles 表 ...');
            $db->query('truncate formax_crm.oa_roles');

            cli_output('清空 formax_crm.oa_user_roles 表 ...');
            $db->query('truncate formax_crm.oa_user_roles');

            cli_output('清空 formax_crm.oa_sales 表 ...');
            $db->query('truncate formax_crm.oa_sales');
        }

        $roles = array(
            array(
                'dept_id' => 0,
                'role_id' => 1,
                'protected' => 1,
                'description' => array('Super Administrator', '超级管理员'),
            ),
            array(
                'dept_id' => 0,
                'role_id' => 2,
                'protected' => 1,
                'description' => array('Administrator', '管理员'),
            ),
            array(
                'dept_id' => 1,
                'role_id' => 3,
                'protected' => 1,
                'description' => array('Sales Director', '销售总监'),
            ),
            array(
                'dept_id' => 1,
                'role_id' => 4,
                'protected' => 1,
                'description' => array('Sales Manager', '销售经理'),
            ),
            array(
                'dept_id' => 1,
                'role_id' => 5,
                'protected' => 1,
                'description' => array('Sales Staff', '销售人员'),
            ),
        );
        foreach ($roles as $role) {
            $cn_description = $role['description'][1];
            $role['description'] = $role['description'][0];
            $model = new \OaRoles;
            $model->save($role);
            \OaTranslates::write('role', $role['role_id'], $cn_description, 'zh-cn');
        }

        $result = $db->query('select * from formaxcrm.crm_user order by id asc');
        cli_output('查询 formaxcrm.crm_user 表，共' . $result->numRows() . '条记录...');

        $succes_nums = 0;
        while ($row = $result->fetch()) {
            // 写入代理关系数据
            if ($row['merchants']) {
                foreach (explode(',', $row['merchants']) as $merchant_id) {
                    $model = new \OaSalesMerchants;
                    $model->save(array(
                        'merchant_id' => $merchant_id,
                        'user_id' => $row['id'],
                        'ctime' => time(),
                    ));
                }
            }

            // 写入部门关系数据
            if ($row['id'] > 1) {
                $model = new \OaDepartmentUsers;
                $model->save(array(
                    'dept_id' => $row['department_id'],
                    'user_id' => $row['id'],
                    'ctime'   => time(),
                ));
            }

            // 写入角色数据
            switch ($row['role_id']) {
                case 0: $role_id = $row['id'] == 1 ? 1 : 2; break;
                case 1: $role_id = 4; break;
                case 2: $role_id = 5; break;
                case 3: $role_id = 3; break;
                default: break;
            }
            if ($role_id) {
                $model = new \OaUserRoles;
                $model->save(array(
                    'user_id' => $row['id'],
                    'role_id' => $role_id,
                ));
            }

            // 写入关系数据
            if ($row['reports_to_uid']) {
                $model = new \OaSales;
                $model->save(array(
                    'user_id' => $row['id'],
                    'leader'  => $row['reports_to_uid'],
                ));
            }

            // 写入用户数据
            $data = array_remove_null(array(
                'user_id'      => $row['id'],
                'email'        => $row['login_email'],
                'old_password' => $row['login_pwd'],
                'first_name'   => $row['first_name'],
                'last_name'    => $row['last_name'],
                'language'     => is_chinese($row['first_name'] . $row['last_name']) ? 'zh-cn' : 'en-us',
                'reg_time'     => strtotime($row['create_date']),
                'status'       => $row['login_enable'] ? \OaUsers::NORMAL : \OaUsers::LOCKED,
                'ctime'        => strtotime($row['create_date']),
            ));

            $model = new \OaUsers;
            if ($success = $model->save($data)) {
                $succes_nums++;
                unset($data['old_password'], $data['ctime']);
                if ($this->args->detail) {
                    cli_output('[成功] => ' . implode(', ', $data));
                } else {
                    echo '>';
                }
            } else {
                if ($this->args->detail) {
                    cli_output('[失败] => ' . $model->getMessage(), 'error');
                } else {
                    echo '.';
                }
            }

        }
        cli_output(PHP_EOL . '用户相关数据导入完成，共成功' . $succes_nums . '条记录', 'success');
    }

    public function importCustomers()
    {
        cli_output(PHP_EOL . '准备导入客户数据', 'info');

        $db = $this->db;

        if ($this->args->clean) {
            cli_output('清空 formax_crm.oa_customer_types 表 ...');
            $db->query('truncate formax_crm.oa_customer_types');

            $db->query("DELETE FROM formax_crm.oa_translates where keyword='customer.type'");

            cli_output('清空 formax_crm.oa_customers 表 ...');
            $db->query('truncate formax_crm.oa_customers');

            cli_output('清空 formax_crm.oa_customer_details 表 ...');
            $db->query('truncate formax_crm.oa_customer_details');
        }

        if ($this->args->clean) {
            $types = array(
                1  => 'Website / 网站客户',
                2  => 'Website No Intention / 网站无意向客户',
                3  => 'Deposit / 网站入金客户',
                4  => 'Potential / 潜在客户',
                5  => 'Individual / 个人客户',
                6  => 'Institutional / 机构客户',
                7  => '​​No intention / 无意向',
                8  => 'Manually Add / 手动新增',
                9  => 'Company Profile / 公司介绍',
                10 => 'Online Consultation / 在线咨询',
            );
            foreach ($types as $type_id => $str) {
                list($en_name, $cn_name) = explode(' / ', $str);
                $arr = array(
                    'type_id' => $type_id,
                    'type_name' => $en_name,
                );
                $model = new \OaCustomerTypes;
                $model->save($arr);
                \OaTranslates::write('customer.type', $type_id, $cn_name, 'zh-cn');
            }
            cli_output(PHP_EOL . '已完成客户类型数据!', 'info');
        }

        $result = $db->query('
            select
                *
            from formaxcrm.crm_account as acc
            left join formaxcrm.crm_account_info as info
                on info.id=acc.id
            order by acc.id asc');
        cli_output('查询 formaxcrm.crm_account 表，共' . $result->numRows() . '条记录...');

        $types = array(
            'null'             => 0,
            'web'              => 1, // 网站客户
            'web_no_intention' => 2, // 网站无意向客户
            'deposit'          => 3, // 网站入金客户
            'leads'            => 4, // 潜在客户
            'individual'       => 5, // 个人客户
            'institutional'    => 6, // 机构客户
            'no_intention'     => 7, // 无意向客户
            'myself'           => 8, // 自己添加的客户
            'corp'             => 9, // 公司介绍
            'ol_consultation'  => 10, // 在线咨询
        );

        $succes_nums = 0;
        while ($row = $result->fetch()) {
            // 将城市名转换为英文
            $country = service('i18n')->reverseTranslate($row['client_country'], 'zh-cn', 'en-us');

            // 查询城市 ID
            $country = \OaCountries::findFirst("country='$country'");
            $country_id = $country ? $country->country_id : 0;

            $data = array_remove_null(array(
                'customer_id'     => $row['id'],
                'type_id'         => $types[$row['client_type']],
                'email'           => $row['client_email'],
                'nickname'        => $row['client_name'],
                'mobile'          => $row['client_mobile'],
                'phone'           => $row['client_phone'],
                'web_uid'         => $row['client_webid'],
                'reg_time'        => strtotime($row['reg_date']),
                'merchant_id'     => $row['client_ib_num'],
                'mt4_demo'        => $row['client_demo'],
                'mt4_live'        => $row['client_live'],
                'country_id'      => $country_id,
                'last_deposited'  => $row['last_deposited'],
                'creator'         => $row['create_uid'],
                'assign_id'       => $row['assigned_id'],
                'assign_time'     => $row['create_time'],
                'manager_user_id' => $row['assigned_team_uid'],
                'sales_user_id'   => $row['assigned_sales_uid'],
                'last_followed'   => strtotime($row['client_follow_date']),
                'deleted'         => $row['is_deleted'],
                'ctime'           => $row['create_time'],
            ));

            $model = new \OaCustomers;
            if ($success = $model->save($data)) {
                $succes_nums++;
                if ($this->args->detail) {
                    cli_output('[成功] => ' . implode(', ', array_slice($data, 0, 10)));
                } else {
                    echo '>';
                }

                $data = array_remove_null(array(
                    'customer_id'  => $row['id'],
                    'first_name'   => $row['client_firstname'],
                    'last_name'    => $row['client_lastname'],
                    'gender'       => $row['client_sex'],
                    'address'      => $row['client_addr'],
                    'company'      => $row['client_company'],
                    'industry'     => $row['client_industry'],
                    'balance'      => $row['client_balance'],
                    'margin_level' => $row['client_margin_level'],
                    'expected_ib'  => $row['client_ib_preview'],
                    'im_type'      => empty($row['client_im']) ? '' : $row['client_im_type'],
                    'im_account'   => $row['client_im'],
                    'description'  => $row['client_descr'],
                ));

                $model = new \OaCustomerDetails;
                if ($success = $model->save($data)) {
                    $this->args->detail && cli_output("\t扩展信息写入成功!", 'green');
                } else {
                    $this->args->detail && cli_output("\t扩展信息写入失败!", 'red');
                }
            } else {
                if ($this->args->detail) {
                    cli_output('[失败] => ' . $model->getMessage(), 'error');
                } else {
                    echo '.';
                }
            }
        }
        cli_output(PHP_EOL . '客户数据导入完成，共成功' . $succes_nums . '条记录', 'success');
    }

    public function importCustomerAssign()
    {
        cli_output(PHP_EOL . '准备导入客户分配数据', 'info');

        $db = $this->db;

        if ($this->args->clean) {
            cli_output('清空 formax_crm.oa_customer_assigns 表 ...');
            $db->query('truncate formax_crm.oa_customer_assigns');
        }

        $result = $db->query('select * from formaxcrm.crm_account_assign order by id asc');
        cli_output('查询 formaxcrm.crm_account_assign 表，共' . $result->numRows() . '条记录...');

        $succes_nums = 0;
        while ($row = $result->fetch()) {
            $data = array(
                'assign_id'   => $row['id'],
                'description' => $row['name'],
                'creator'     => $row['create_uid'],
                'customers'   => \OaCustomers::count('assign_id=' . $row['id']),
                'ctime'       => strtotime($row['create_date']),
            );

            $model = new \OaCustomerAssigns;
            if ($success = $model->save($data)) {
                $succes_nums++;
                if ($this->args->detail) {
                    cli_output('[成功] => ' . implode(', ', $data));
                } else {
                    echo '>';
                }
            } else {
                if ($this->args->detail) {
                    cli_output('[失败] => ' . $model->getMessage(), 'error');
                } else {
                    echo '.';
                }
            }
        }

        cli_output(PHP_EOL . '客户分配数据导入完成，共成功' . $succes_nums . '条记录', 'success');
    }

    public function importCustomerLogs()
    {
        cli_output(PHP_EOL . '准备导入客户跟进日志', 'info');

        $db = $this->db;

        if ($this->args->clean) {
            cli_output('清空 formax_crm.oa_customer_follow_logs 表 ...');
            $db->query('truncate formax_crm.oa_customer_follow_logs');
        }

        $result = $db->query('select * from formaxcrm.crm_account_log order by id asc');
        cli_output('查询 formaxcrm.crm_account_log 表，共' . $result->numRows() . '条记录...');

        $succes_nums = 0;
        while ($row = $result->fetch()) {
            $follow_mode = trim($row['log_type']);
            if ($follow_mode == 'mail') {
                $follow_mode = 'email';
            } elseif (empty($follow_mode)) {
                $follow_mode = 'other';
            }

            $data = array_remove_null(array(
                'log_id'         => $row['id'],
                'customer_id'    => $row['client_id'],
                'follow_user_id' => $row['log_uid'],
                'follow_mode'    => $follow_mode,
                'description'    => $row['descr'],
                'screenshot'     => str_replace('/uploadfile/', str_replace(DOC_PATH, '', config('upload.basePath')) . '/follow/', $row['screenshot']),
                'ctime'          => strtotime($row['create_date']),
            ));

            $model = new \OaCustomerFollowLogs;
            if ($success = $model->save($data)) {
                $succes_nums++;
                unset($data['description'], $data['screenshot']);
                if ($this->args->detail) {
                    cli_output('[成功] => ' . implode(', ', $data));
                } else {
                    echo '>';
                }
            } else {
                if ($this->args->detail) {
                    cli_output('[失败] => ' . $model->getMessage(), 'error');
                } else {
                    echo '>';
                }
            }
        }
        cli_output(PHP_EOL . '客户跟进日志导入完成，共成功' . $succes_nums . '条记录', 'success');
    }
}
